// Copyright Epic Games, Inc. All Rights Reserved. // 版权声明，Epic Games 公司保留所有权利

#pragma once // 头文件保护宏，防止重复包含

#include "ActiveGameplayEffectHandle.h" // 包含主动游戏效果句柄的头文件
#include "Subsystems/WorldSubsystem.h" // 包含世界子系统的头文件
#include "GameplayAbilitySpecHandle.h" // 包含游戏能力规格句柄的头文件
#include "Templates/SubclassOf.h" // 包含子类模板的头文件

#include "LyraGlobalAbilitySystem.generated.h" // 包含由 Unreal Header Tool 生成的头文件

class UGameplayAbility; // 前向声明 UGameplayAbility 类
class UGameplayEffect; // 前向声明 UGameplayEffect 类
class ULyraAbilitySystemComponent; // 前向声明 ULyraAbilitySystemComponent 类
class UObject; // 前向声明 UObject 类
struct FActiveGameplayEffectHandle; // 前向声明 FActiveGameplayEffectHandle 结构体
struct FFrame; // 前向声明 FFrame 结构体（通常用于 Unreal 的反射系统）
struct FGameplayAbilitySpecHandle; // 前向声明 FGameplayAbilitySpecHandle 结构体

USTRUCT() // 声明一个 USTRUCT，用于反射和序列化
struct FGlobalAppliedAbilityList // 全局已应用能力列表结构体
{
	GENERATED_BODY() // 宏，生成结构体所需的反射代码

	UPROPERTY() // 声明一个 UPROPERTY，用于反射和垃圾回收
	TMap<TObjectPtr<ULyraAbilitySystemComponent>, FGameplayAbilitySpecHandle> Handles; // 映射表，键为 Lyra ASC 对象指针，值为游戏能力规格句柄

	/**
	 * 将指定的能力添加到指定的 Ability System Component (ASC)
	 * @param Ability 要添加的能力类
	 * @param ASC 目标能力系统组件
	 */
	void AddToASC(TSubclassOf<UGameplayAbility> Ability, ULyraAbilitySystemComponent* ASC);

	/**
	 * 从指定的 ASC 移除能力
	 * @param ASC 目标能力系统组件
	 */
	void RemoveFromASC(ULyraAbilitySystemComponent* ASC);

	/**
	 * 从所有 ASC 移除能力
	 */
	void RemoveFromAll();
};

USTRUCT() // 声明一个 USTRUCT，用于反射和序列化
struct FGlobalAppliedEffectList // 全局已应用效果列表结构体
{
	GENERATED_BODY() // 宏，生成结构体所需的反射代码

	UPROPERTY() // 声明一个 UPROPERTY，用于反射和垃圾回收
	TMap<TObjectPtr<ULyraAbilitySystemComponent>, FActiveGameplayEffectHandle> Handles; // 映射表，键为 Lyra ASC 对象指针，值为主动游戏效果句柄

	/**
	 * 将指定的效果添加到指定的 Ability System Component (ASC)
	 * @param Effect 要添加的效果类
	 * @param ASC 目标能力系统组件
	 */
	void AddToASC(TSubclassOf<UGameplayEffect> Effect, ULyraAbilitySystemComponent* ASC);

	/**
	 * 从指定的 ASC 移除效果
	 * @param ASC 目标能力系统组件
	 */
	void RemoveFromASC(ULyraAbilitySystemComponent* ASC);

	/**
	 * 从所有 ASC 移除效果
	 */
	void RemoveFromAll();
};

UCLASS() // 声明一个 UCLASS，用于反射和序列化
class ULyraGlobalAbilitySystem : public UWorldSubsystem // Lyra 全局能力系统类，继承自 UWorldSubsystem
{
	GENERATED_BODY() // 宏，生成类所需的反射代码

public:
	ULyraGlobalAbilitySystem(); // 构造函数声明

	/**
	 * 将能力应用于所有已注册的 ASC（蓝图可调用，仅限权威端）
	 * @param Ability 要应用的能力类
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Lyra")
	void ApplyAbilityToAll(TSubclassOf<UGameplayAbility> Ability);

	/**
	 * 将效果应用于所有已注册的 ASC（蓝图可调用，仅限权威端）
	 * @param Effect 要应用的效果类
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category="Lyra")
	void ApplyEffectToAll(TSubclassOf<UGameplayEffect> Effect);

	/**
	 * 从所有已注册的 ASC 移除能力（蓝图可调用，仅限权威端）
	 * @param Ability 要移除的能力类
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Lyra")
	void RemoveAbilityFromAll(TSubclassOf<UGameplayAbility> Ability);

	/**
	 * 从所有已注册的 ASC 移除效果（蓝图可调用，仅限权威端）
	 * @param Effect 要移除的效果类
	 */
	UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category = "Lyra")
	void RemoveEffectFromAll(TSubclassOf<UGameplayEffect> Effect);

	/**
	 * 注册一个 ASC 到全局系统，并应用所有已激活的全局效果/能力
	 * @param ASC 要注册的能力系统组件
	 */
	void RegisterASC(ULyraAbilitySystemComponent* ASC);

	/**
	 * 从全局系统注销一个 ASC，并移除所有已激活的全局效果/能力
	 * @param ASC 要注销的能力系统组件
	 */
	void UnregisterASC(ULyraAbilitySystemComponent* ASC);

private:
	UPROPERTY() // 声明一个 UPROPERTY，用于反射和垃圾回收
	TMap<TSubclassOf<UGameplayAbility>, FGlobalAppliedAbilityList> AppliedAbilities; // 映射表，键为能力类，值为全局已应用能力列表

	UPROPERTY() // 声明一个 UPROPERTY，用于反射和垃圾回收
	TMap<TSubclassOf<UGameplayEffect>, FGlobalAppliedEffectList> AppliedEffects; // 映射表，键为效果类，值为全局已应用效果列表

	UPROPERTY() // 声明一个 UPROPERTY，用于反射和垃圾回收
	TArray<TObjectPtr<ULyraAbilitySystemComponent>> RegisteredASCs; // 已注册的 ASC 数组
};